package com.nuyoah.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.nuyoah.common.dto.UserDto;
import com.nuyoah.common.lang.Result;
import com.nuyoah.entity.Student;
import com.nuyoah.entity.User;
import com.nuyoah.service.StudentService;
import com.nuyoah.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 学生信息相关接口
 *
 * @author xyx
 * @since 2024-06-03
 */
@RestController
@RequestMapping("/student")
public class StudentController {

    @Autowired
    private UserService userService;

    @Autowired
    private StudentService studentService;


    /**
     * 更新学生信息接口。
     * 通过@RequestBody注解将传入的UserDto对象绑定到方法参数student上，@Validated注解用于验证输入数据的合法性。
     *
     * @param student 包含待更新的学生信息的UserDto对象。
     * @return 更新成功返回带有成功消息的结果对象，更新失败返回带有失败消息的结果对象。
     */
    // 更新学生信息接口
    @RequestMapping("/updateStudentInfo")
    public Result updateStudentInfo(@Validated @RequestBody UserDto student) {
        // 验证学生ID是否存在，如果不存在，则返回失败结果
        if (studentService.getById(student.getId()) == null) {
            return Result.fail("学生ID不存在，更新失败");
        }
        // 创建User对象，用于更新用户相关信息
        User u = new User();
        // 创建Student对象，用于更新学生相关信息
        Student s = new Student();

        // 设置用户ID，用于后续更新操作
        u.setId(student.getId());
        u.setUsername(student.getUsername());
        u.setRealName(student.getRealName());
        u.setPhone(student.getPhone());
        u.setAge(student.getAge());
        u.setGender(student.getGender());
        // 通过userService更新User对象信息
        userService.updateById(u);

        // 设置Student对象的ID，以及其他相关信息
        s.setId(student.getId());
        s.setSchool(student.getSchool());
        s.setSClass(student.getSClass());

        // 通过studentService更新Student对象信息
        studentService.updateById(s);

        // 更新成功，返回成功结果
        return Result.succ("更新成功");
    }


    /**
     * 学生个人信息接口
     *
     * @return Result 对象，包含查询成功的信息或错误消息。
     */
    //学生个人信息接口
    @RequestMapping("/getStudentInfo")
    public Result getStudentInfo() {
        try {
            Integer ids = StpUtil.getLoginIdAsInt();;
            //通过id到用户表中查询用户信息
            User user = userService.getUserById(ids);
            // 如果用户不存在，则返回错误信息
            if (user == null) {
                return Result.fail("用户不存在");
            }
            // 获取用户的ID，用于进一步查询学生详细信息
            Integer id = user.getId();
            // 创建UserDto对象，用于封装查询到的学生信息
            // 创建UserDto对象来封装学生信息
            //根据用户id查询user表和student表，返回学生信息（学生信息中应包含username，realName，email，phone，sClass，learningHistory）
            UserDto student = new UserDto();
            // 将用户基本信息（用户名、真实姓名、电子邮件、电话）设置到StudentDto中
            // 设置学生的用户名、真实姓名、电子邮件等基本信息
            student.setUsername(user.getUsername());
            student.setRealName(user.getRealName());
            student.setEmail(user.getEmail());
            student.setPhone(user.getPhone());

            // 根据用户ID查询Student实体，获取学生详细信息（班级和学习历史）
            // 根据用户ID查询学生详细信息，包括班级和学习历史
            Student s = studentService.getByUserId(id);
            // 将学生详细信息（班级和学习历史）设置到StudentDto中
            // 设置学生的班级和学习历史信息
            student.setSClass(s.getSClass());
            student.setLearningHistory(s.getLearningHistory());
            student.setAge(user.getAge());
            student.setGender(user.getGender());
            student.setSchool(s.getSchool());
            student.setId(user.getId());

            // 返回成功结果，包含查询到的学生信息
            // 返回成功结果，包含完整的学生信息
            return Result.succ(student);
        } catch (Exception e) {
            // 捕获任何异常，打印异常堆栈跟踪
            // 捕获任何异常，打印堆栈跟踪，并返回失败结果，说明获取学生信息失败
            e.printStackTrace();
            // 返回失败结果，说明获取学生信息失败
            return Result.fail("获取学生信息失败");
        }
    }


    /**
     * 处理学生注册请求。
     *
     * @param student 包含用户注册信息的数据传输对象（DTO）。
     * @return 注册结果，成功或失败的原因。
     * <p>
     * 此方法首先验证用户名是否已存在，如果存在，则返回失败结果。
     * 如果用户名不存在，它将创建一个新的用户对象，并使用BCrypt加密密码。
     * 然后，它将用户信息保存到数据库中。
     * 接下来，它创建一个学生对象，并将用户ID、班级和学习历史关联起来，然后保存学生信息。
     * 最后，为该用户分配学生角色，并返回注册成功的消息。
     */
    //学生注册接口
    @RequestMapping("/register")
    public Result register(@Validated @RequestBody UserDto student) {
        // 验证用户名是否已存在
        if (userService.getByUsername(student.getUsername()) != null) {
            return Result.fail("用户名已存在，请重新注册");
        }

        User user = new User();
        user.setUsername(student.getUsername());
        user.setPassword(DigestUtil.md5Hex(student.getPassword()));
        user.setRealName(student.getRealName());
        user.setEmail(student.getEmail());
        user.setPhone(student.getPhone());
        user.setAge(student.getAge());
        user.setGender(student.getGender());
        userService.save(user);

        // 创建学生对象并保存到数据库
        Student s = new Student();
        s.setId(user.getId());
        s.setSClass(student.getSClass());
        s.setLearningHistory(student.getLearningHistory());
        s.setSchool(student.getSchool());
        studentService.save(s);

        //在user_role表中插入一条记录，将学生的角色绑定到用户
        userService.insertUserRoleBinding(user.getId(), 2);
        return Result.succ("注册成功");
    }

}
